package com.capgemini.rdlgae.service

import groovyx.net.http.EncoderRegistry 
import groovyx.net.http.HTTPBuilder
import static groovyx.net.http.ContentType.URLENC 
import org.codehaus.groovy.grails.web.servlet.DefaultGrailsApplicationAttributes 
import org.codehaus.groovy.grails.commons.*
import grails.util.GrailsWebUtil
import javax.servlet.http.HttpServletRequest
import org.codehaus.groovy.grails.web.context.ServletContextHolder
import org.codehaus.groovy.grails.web.servlet.DefaultGrailsApplicationAttributes
import org.springframework.core.io.*
import org.springframework.web.context.request.RequestContextHolder
import org.springframework.web.context.support.WebApplicationContextUtils
import java.util.HashMap;
import java.text.SimpleDateFormat;

import com.capgemini.rdlgae.domain.AbstractPlat 
import com.capgemini.rdlgae.domain.Commande;


class EnvoiMailService {
	
	def mailService
	static PATH_TO_MAILVIEWS = "/WEB-INF/grails-app/views"
	boolean transactional = true
	
	def ajouterUneUnite(def recapitulatifPlat, AbstractPlat plat){
		
		if(recapitulatifPlat.containsKey(plat?.nom)){
			Integer value = recapitulatifPlat.get(plat?.nom)
			recapitulatifPlat.put(plat?.nom, value+1)
		}
		else
			recapitulatifPlat.put(plat?.nom, 1)
		
	}
	def envoiMail() {
		log.info "Appel au service d'envoi de mail"
		Calendar dateReference = Calendar.getInstance();
		dateReference.clear(Calendar.AM_PM);
		dateReference.clear(Calendar.HOUR_OF_DAY);
		dateReference.clear(Calendar.HOUR);
		dateReference.clear(Calendar.MINUTE);
		dateReference.clear(Calendar.SECOND);
		dateReference.clear(Calendar.MILLISECOND);
		
		def commandes = Commande.findAllByDateCommande(dateReference.getTime())

		//Existe t il des commandes à envoyer pour aujourd'hui
		if(commandes != null && commandes.size() > 0 ) {
			log.info "Il existe ${commandes.size()} commande(s) à envoyer"
			def recapitulatifPlat = [:]
			
			def nbPlat = commandes.size()
			def total = 0.0
			commandes.each(){ commande ->
				
				/*
				 * Calcul du total
				 */
				total = total.add(commande.total)
				
				/*
				 * Création du récapitulatif
				 */
				if(commande.entree != null)
					ajouterUneUnite(recapitulatifPlat, commande.entree)
				if(commande.plat != null)
					ajouterUneUnite(recapitulatifPlat, commande.plat)
				if(commande.dessert != null)
					ajouterUneUnite(recapitulatifPlat, commande.dessert)
				
			}
			
			/*
			 * Tri du récapitulatif
			 */
			
			recapitulatifPlat.sort { a, b -> b.value <=> a.value }
			

			def http = new HTTPBuilder( 'http://rdlgae.appspot.com/' )
			http.encoderRegistry = new EncoderRegistry( charset: 'utf-8' ) 
			
			try{
				
				def content = renderMailView("/email/template",[commandes:commandes, dateCommande:dateReference.getTime(),  total: total, recapitulatifPlat: recapitulatifPlat ])

				SimpleDateFormat sdf = new SimpleDateFormat("dd-MM-yy");
				def dateCommande =  sdf.format(dateReference.getTime())
				def to = ConfigurationHolder.config.mail.to
				def cc = ConfigurationHolder.config.mail.cc
				def fromLabel = ConfigurationHolder.config.mail.fromLabel
				def subject = ConfigurationHolder.config.mail.subject
				
				def postBody = [dateCommande: dateCommande, to:to, cc: cc, fromLabel: fromLabel, subject: subject, content:content]
				
				http.post( path: 'send', body: postBody,
						requestContentType: URLENC ) { resp ->
							
							if(resp.statusLine.statusCode == 200){
								commandes.each(){ commande ->
									commande.envoyee = true
									commande.save()
								}
							}

							else if(resp.statusLine.statusCode == 400){
								println "envoi echoué !"
							}
					}
				
			}
			catch(Exception ex){
				
				log.debug ex.getMessage()
				
			}
			
		}
		
	}
	def renderMailView(templateName, model) {
		if(!mailService.groovyPagesTemplateEngine) throw new IllegalStateException("Property [groovyPagesTemplateEngine] must be set!")
		assert templateName
		def engine = mailService.groovyPagesTemplateEngine
		def requestAttributes = RequestContextHolder.getRequestAttributes()
		boolean unbindRequest = false
		// outside of an executing request, establish a mock version
		if(!requestAttributes) {
			def servletContext  = ServletContextHolder.getServletContext()
			def applicationContext = WebApplicationContextUtils.getRequiredWebApplicationContext(servletContext)
			requestAttributes = GrailsWebUtil.bindMockWebRequest(applicationContext)
			unbindRequest = true
		}
		def servletContext = requestAttributes.request.servletContext
		def request = requestAttributes.request
		def grailsAttributes = new DefaultGrailsApplicationAttributes(servletContext);
		// See if the application has the view for it
		def uri = getMailViewUri(templateName, request)
		def r = engine.getResourceForUri(uri)
		// Try plugin view if not found in application
		if (!r || !r.exists()) {
			if (log.debugEnabled) {
				log.debug "Could not locate email view ${templateName} at ${uri}, trying plugin"
			}
			
		}
		def t = engine.createTemplate( r )
		def out = new StringWriter();
		def originalOut = requestAttributes.getOut()
		requestAttributes.setOut(out)
		try {
			if(model instanceof Map) {
				t.make( model ).writeTo(out)
			}
			else {
				t.make().writeTo(out)
			}
		}
		finally {
			requestAttributes.setOut(originalOut)
			if(unbindRequest) {
				RequestContextHolder.setRequestAttributes(null)
			}
		}
		
		return out.toString() // @todo Spring mail helper will not set correct mime type if we give it XHTML
		
	}
	
	protected String getMailViewUri(String viewName, HttpServletRequest request) {
		def buf = new StringBuilder(PATH_TO_MAILVIEWS)
		
		if(viewName.startsWith("/")) {
			def tmp = viewName[1..-1]
			if(tmp.indexOf('/') > -1) {
				def i = tmp.lastIndexOf('/')
				buf << "/${tmp[0..i]}/${tmp[(i+1)..-1]}"
			}
			else {
				buf << "/${viewName[1..-1]}"
			}
		}
		else {
			if (!request) throw new IllegalArgumentException(
				"Mail views cannot be loaded from relative view paths where there is no current HTTP request")
			def grailsAttributes = new DefaultGrailsApplicationAttributes(request.servletContext)
			buf << "${grailsAttributes.getControllerUri(request)}/${viewName}"
		}
		return buf.append(".gsp").toString()
	}
	
}
